package qq2564874169.tuaotuao.fx.app;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class FxRequestMappingHandler extends RequestMappingHandlerMapping {
    private Map<Method, HandlerMethod> methodMap = new ConcurrentHashMap<>();
    @Autowired
    private FxSpringApp app;

    @Override
    protected HandlerMethod createHandlerMethod(Object handler, Method method) {
        HandlerMethod hm = methodMap.get(method);
        if (hm == null) {
            if (handler instanceof String) {
                hm = new FxHandlerMethod((String) handler, obtainApplicationContext(), method);
            } else {
                hm = super.createHandlerMethod(handler, method);
            }
            methodMap.put(method, hm);
        }
        return hm;
    }

    private class FxHandlerMethod extends HandlerMethod {
        public FxHandlerMethod(String bean, BeanFactory beanFactory, Method method) {
            super(bean, beanFactory, method);
        }

        @Override
        public HandlerMethod createWithResolvedBean() {
            HandlerMethod hm = null;
            var request = Utils.getRequest();
            var args = new HandlerEventArgs(request, getBeanType());
            app.getMvcEvents().onHandlerBefore(app, args);
            if (args.handler != null) {
                hm = new HandlerMethod(args.handler, this.getMethod());
            }
            if (hm == null) {
                hm = super.createWithResolvedBean();
                args.handler = hm.getBean();
            }
            Object bak = args.handler;
            app.getMvcEvents().onHandlerAfter(app, args);
            if (bak != args.handler) {
                hm = new HandlerMethod(args.handler, this.getMethod());
            }
            return hm;
        }
    }
}